package cn.hznc.controller.service.toolAnalyze;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hznc.domain.entity.*;
import cn.hznc.domain.request.life.QryToolLifeReq;
import cn.hznc.domain.response.PageResult;
import cn.hznc.mapper.*;
import cn.hznc.repository.InventoryLocationRespository;
import cn.hznc.repository.ToolPartRespository;
import cn.hznc.repository.TypeRepository;
import cn.hznc.utils.CommonUtil;
import cn.hznc.vo.LocationNameVo;
import cn.hznc.vo.ToolLifeAnalyzeReloadVo;
import cn.hznc.vo.ToolLifeAnalyzeVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import org.apache.commons.lang.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ToolLifeAnalyzeService {
    @Resource
    private ToolPartMapper toolPartMapper;
    @Resource
    private TypeItemMapper typeItemMapper;
    @Resource
    private InventoryLocationRespository inventoryLocationRespository;
    @Resource
    private ToolConsumptionandUsageAnalysisService toolConsumptionandUsageAnalysisService;
    @Resource
    private TypeMapper typeMapper;

    @Resource
    private TypeRepository typeRepository;

    @Resource
    private ToolPartRespository toolPartRespository;

    @Resource
    private ToolLifeMapper toolLifeMapper;

//    public PageResult<ToolLifeAnalyzeEntity> queryToolLifeAnalyze(ToolLifeAnalyzeReq toolLifeAnalyzeReq){
//        LambdaQueryWrapper<ToolPartEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//
//        List<String> partno = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(toolLifeAnalyzeReq.getIds())){
//            LambdaQueryWrapper<TypeEntity> lambdaQueryWrapper2 = new LambdaQueryWrapper<>();
//            lambdaQueryWrapper2.in(TypeEntity::getId,toolLifeAnalyzeReq.getIds());
//            List<TypeEntity> typeEntityList = typeMapper.selectList(lambdaQueryWrapper2);
//            typeEntityList.forEach(typeEntity -> {
//                partno.add(typeEntity.getTypeName());
//                toolConsumptionandUsageAnalysisService.getTypeName(partno,typeEntity.getId());
//            });
//        }
//        if (CollectionUtil.isNotEmpty(partno))
//        lambdaQueryWrapper.in(ToolPartEntity::getPartno,partno);
////        if (CollectionUtil.isNotEmpty(partno)){
//////            List<String> toolTypes = partno;
////            partno.forEach(t ->{
////                lambdaQueryWrapper.or().likeRight(ToolPartEntity::getToolType,t);
////            });
////        }
//
//        if (StringUtils.isNotEmpty(toolLifeAnalyzeReq.getPartno())){
//            lambdaQueryWrapper.like(ToolPartEntity::getPartno,toolLifeAnalyzeReq.getPartno());
//            lambdaQueryWrapper.orderByDesc(ToolPartEntity::getRemainingLife);
//        }
//        List<ToolPartEntity> toolPartEntities = toolPartMapper.selectList(lambdaQueryWrapper);
//        Map<String, List<ToolPartEntity>> map = toolPartEntities.stream()
//                .filter(item-> StringUtils.isNotBlank(item.getPartno())).collect(Collectors.groupingBy(ToolPartEntity::getPartno));
//        Iterator<Map.Entry<String,List<ToolPartEntity>>> entries = map.entrySet().iterator();
////        PageHelper.startPage(toolLifeAnalyzeReq.getPageNo(), toolLifeAnalyzeReq.getPageSize());
//        List<ToolLifeAnalyzeEntity> toolLifeAnalyzeEntityList = new ArrayList<>();
//        int flag=0;
//        int startPage = (toolLifeAnalyzeReq.getPageNo()-1)* toolLifeAnalyzeReq.getPageSize();
//        int endPage = toolLifeAnalyzeReq.getPageNo()* toolLifeAnalyzeReq.getPageSize();
//        while (entries.hasNext()){
//            Map.Entry<String,List<ToolPartEntity>> entry = entries.next();
//            if(flag<endPage)
//            {
//                flag++;
//            }else {break;}
//            if (flag>startPage){
//                ToolLifeAnalyzeEntity toolLifeAnalyzeEntity = new ToolLifeAnalyzeEntity();
//                List<Double> list = new ArrayList<>();
//                List<String> typeNames = new ArrayList<>();
//                List<Integer> lifeList = new ArrayList<>();
//                entry.getValue().forEach(toolPartEntity -> {
//                    if (StringUtils.isNotEmpty(toolPartEntity.getToolType())&&StringUtils.isEmpty(toolLifeAnalyzeEntity.getTypeName())){
//                        typeNames.add(typeItemMapper.getTypeNameByType(toolPartEntity.getToolType()));
//                    }
//                    try {
//                        if (toolPartEntity.getIsDamage() == 1){
//                            String timeUsage = toolPartEntity.getTimeUsage().substring(0,toolPartEntity.getTimeUsage().length()-1);
//                            Double time = Double.valueOf(timeUsage);
//                            list.add(time);
//                        }
//                        String remainingLife = toolPartEntity.getRemainingLife().substring(0,toolPartEntity.getRemainingLife().length()-1);
//                        Integer averageLife = Integer.valueOf(remainingLife);
//
//                        String life = toolPartEntity.getLife().substring(0,toolPartEntity.getLife().length()-1);
//                        Integer l = Integer.valueOf(life);
//                        lifeList.add(l);
////                        list.add(averageLife);
//                    }catch (Exception e){
//
//                    }
//                });
//                if (CollectionUtil.isNotEmpty(typeNames))
//                    toolLifeAnalyzeEntity.setTypeName(typeNames.get(0));
//                Double d = list.stream().collect(Collectors.averagingDouble(Double::intValue));
//                toolLifeAnalyzeEntity.setAverageLife(String.valueOf(d));
//                toolLifeAnalyzeEntity.setPartno(entry.getKey());
//                toolLifeAnalyzeEntityList.add(toolLifeAnalyzeEntity);
//                if (CollectionUtil.isNotEmpty(lifeList))
//                    toolLifeAnalyzeEntity.setLife(String.valueOf(lifeList.get(0)));
//            }
//
//        }
////        ;
//        PageInfo<ToolLifeAnalyzeEntity> result = new PageInfo<>(toolLifeAnalyzeEntityList);
//        return new PageResult<>(result.getList(), (long)map.size());
//
//    }

    public PageResult<ToolLifeAnalyzeDetailEntity> queryToolLifeAnalyzeDetailByPartno(Integer pageNo,
                                                                                      Integer pageSize,
                                                                                      String partno,
                                                                                      String uniqueId,
                                                                                      Integer isDamage) {
//        PageHelper.startPage(pageNo, pageSize);
//        int flag=0;
//        int startPage = (pageNo-1)* pageSize;
//        int endPage = pageNo* pageSize;
        LambdaQueryWrapper<ToolPartEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(partno))
            lambdaQueryWrapper.eq(ToolPartEntity::getPartno,partno);
        if (StringUtils.isNotEmpty(uniqueId))
            lambdaQueryWrapper.like(ToolPartEntity::getUniqueId,uniqueId);
        if (ObjectUtil.isNotEmpty(isDamage)){
            lambdaQueryWrapper.eq(ToolPartEntity::getIsDamage,isDamage);
        }
        List<ToolPartEntity> toolPartEntityList = toolPartMapper.selectList(lambdaQueryWrapper);
        List<ToolLifeAnalyzeDetailEntity> toolLifeAnalyzeDetailEntities = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(toolPartEntityList)){
            toolPartEntityList.forEach(toolPartEntity -> {
                ToolLifeAnalyzeDetailEntity toolLifeAnalyzeDetailEntity = new ToolLifeAnalyzeDetailEntity();
                if (toolPartEntity.getIsDamage() == 0){
                    toolLifeAnalyzeDetailEntity.setIsDamage("未报废");
                }else {
                    toolLifeAnalyzeDetailEntity.setIsDamage("报废");
                }
                toolLifeAnalyzeDetailEntity.setLife(toolPartEntity.getLife());
                toolLifeAnalyzeDetailEntity.setPartno(toolPartEntity.getPartno());
                toolLifeAnalyzeDetailEntity.setRfid(toolPartEntity.getUniqueId());
                toolLifeAnalyzeDetailEntity.setTypeName(typeItemMapper.getTypeNameByType(toolPartEntity.getToolType()));
                toolLifeAnalyzeDetailEntity.setTimeUsage(toolPartEntity.getTimeUsage());
                LocationNameVo locationNameVo = inventoryLocationRespository.queryLocation(toolPartEntity.getId());
                if (locationNameVo != null){
                    StringBuilder stringBuilder = new StringBuilder();
                    String locationName = stringBuilder.append(locationNameVo.getTypeName()).append("-")
                            .append(locationNameVo.getWarehouseName()).append("-库位")
                            .append(locationNameVo.getLocationNum()).toString();
                    toolLifeAnalyzeDetailEntity.setToolPlace(locationName);
                }
                toolLifeAnalyzeDetailEntities.add(toolLifeAnalyzeDetailEntity);
            });
        }
        PageInfo<ToolLifeAnalyzeDetailEntity> result = new PageInfo<>(CommonUtil.pageList(toolLifeAnalyzeDetailEntities,pageNo,pageSize));
        return new PageResult<>(result.getList(), (long)toolLifeAnalyzeDetailEntities.size());

    }

    public List<String> queryPartnosById(List<Integer> ids) {
        List<Integer> childIds = new ArrayList<>();
        //获取子节点id
        if(CollectionUtil.isEmpty(ids)){
            List<Integer> byParentIds = typeRepository.getByParentIds(-1);
            ids.addAll(byParentIds);
        }
        if(CollectionUtil.isNotEmpty(ids)){
            getIdsReload(childIds , ids);
//            ids.forEach(pid->{
//                getIds(childIds , pid);
//            });
            if(CollectionUtil.isNotEmpty(childIds)){
                return typeRepository.queryPartnosById(childIds.stream().distinct().collect(Collectors.toList()));
            }
        }
        return new ArrayList<>();
    }

    private void getIds(List<Integer> childIds , Integer pid){
        List<Integer> result = typeRepository.getByParentIds(pid);
        if(CollectionUtil.isNotEmpty(result)){
            result.forEach(subPid ->{
                getIds(childIds ,subPid);
            });
        }
        childIds.add(pid);
    }

    private void getIdsReload(List<Integer> childIds , List<Integer> pids){
        List<Integer> byParentIds = typeRepository.getByParentIdsReload(pids);
        if(CollectionUtil.isNotEmpty(byParentIds)){
            getIdsReload(childIds , byParentIds);
        }
        childIds.addAll(pids);
    }

    public Object queryToolLifeAnalyze(QryToolLifeReq qryToolLifeReq) {
        List<ToolLifeAnalyzeReloadVo> resultList = new ArrayList<>();
        List<ToolLifeAnalyzeReloadVo> pageList = new ArrayList<>();
        //PageHelper.startPage(qryToolLifeReq.getPageNum() , qryToolLifeReq.getPageSize());
        List<ToolLifeAnalyzeVo> list = toolPartRespository.queryToolLifeAnalyze(qryToolLifeReq);
        //遍历获取设置double类型寿命和使用寿命
        if(CollectionUtil.isNotEmpty(list)){
            list.forEach(toolLifeAnalyzeVo -> {
                if(StringUtils.isNotBlank(toolLifeAnalyzeVo.getTimeUsage())){
                    toolLifeAnalyzeVo.setTimeUsageDouble(Double.valueOf(toolLifeAnalyzeVo.getTimeUsage().substring(0 , toolLifeAnalyzeVo.getTimeUsage().length()-1)));
                }else {
                    toolLifeAnalyzeVo.setTimeUsageDouble(0.0);
                }
                if(StringUtils.isNotBlank(toolLifeAnalyzeVo.getTimeUsage())){
                    toolLifeAnalyzeVo.setLifeDouble(Double.valueOf(toolLifeAnalyzeVo.getLife().substring(0 , toolLifeAnalyzeVo.getLife().length()-1)));
                }else{
                    toolLifeAnalyzeVo.setLifeDouble(0.0);
                }
            });
            //根据partno分组
            Map<String, List<ToolLifeAnalyzeVo>> groupByPartno = list.stream().collect(Collectors.groupingBy(ToolLifeAnalyzeVo::getPartno));
            if(CollectionUtil.isNotEmpty(groupByPartno)){
                groupByPartno.forEach((k , v) ->{
                    List<Double> timeUsageMap = v.stream().map(ToolLifeAnalyzeVo::getTimeUsageDouble).collect(Collectors.toList());
                    List<Double> toolLifeMap = v.stream().map(ToolLifeAnalyzeVo::getLifeDouble).collect(Collectors.toList());
                    ToolLifeAnalyzeReloadVo toolLifeAnalyzeReloadVo = new ToolLifeAnalyzeReloadVo();
                    toolLifeAnalyzeReloadVo.setPartno(k);
                    toolLifeAnalyzeReloadVo.setMinTimeUsage(CollectionUtil.min(timeUsageMap));
                    toolLifeAnalyzeReloadVo.setMinToolLife(CollectionUtil.min(toolLifeMap));
                    toolLifeAnalyzeReloadVo.setMean(CommonUtil.calculateAvgValue(timeUsageMap));
                    toolLifeAnalyzeReloadVo.setStandardDeviation(CommonUtil.calculateStandardDeviation(timeUsageMap));
                    toolLifeAnalyzeReloadVo.setExpectedValue(calculateExpectedValue(timeUsageMap));
                    resultList.add(toolLifeAnalyzeReloadVo);
                });
            }
        }
        if(CollectionUtil.isNotEmpty(resultList)){
            pageList = CommonUtil.pageList(resultList , qryToolLifeReq.getPageNum() , qryToolLifeReq.getPageSize());
            //设置配置额定寿命
            if(CollectionUtil.isNotEmpty(pageList)){
                pageList.forEach(toolLifeAnalyzeReloadVo -> {
                    QueryWrapper<ToolLifeEntity> wrapper = new QueryWrapper<>();
                    wrapper.eq("classify" , toolLifeAnalyzeReloadVo.getPartno());
                    List<ToolLifeEntity> toolLifeEntity = toolLifeMapper.selectList(wrapper);
                    if(CollectionUtil.isNotEmpty(toolLifeEntity)){
                        toolLifeAnalyzeReloadVo.setToolLifeConfig(toolLifeEntity.get(0).getLife().toString());
                    }
                });
            }
        }
        return new PageResult<>(pageList , (long)resultList.size() );
    }

    /**
     * 计算数学期望
     * @param timeUsageMap
     * @return
     */
    public double calculateExpectedValue(List<Double> timeUsageMap) {
        double expectedValue = 0.0;
        if(CollectionUtil.isNotEmpty(timeUsageMap)){
            for (Double timeUsage : timeUsageMap) {
                expectedValue += timeUsage * CommonUtil.calculateRate(CommonUtil.calculateAvgValue(timeUsageMap) , CommonUtil.calculateStandardDeviation(timeUsageMap) , timeUsage);
            }
        }
        return expectedValue;
    }
}
